package com.task;

import com.task.model.SysJobPO;
import com.task.service.SysJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.scheduling.support.CronTrigger;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: cxt
 * @time: 2023/2/7
 * 通过 SchedulingConfigurer 实现动态定时任务
 */
@Configuration
public abstract class SchedulingDemo implements SchedulingConfigurer {

    private SysJobService sysJobService;

    /**
     * 这个方法是在spring初始化时候执行
     * 这个方法里面需要拉取库里面需要进行执行的任务，添加到定时器中
     *
     * @param taskRegistrar
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 1、默认单线程方式，如果需要多线程时候这里可以进行配置
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();
        taskRegistrar.setTaskScheduler(taskScheduler);

        // 2、单个定时任务
        // 执行定时任务
        taskRegistrar.addTriggerTask(this::taskService, triggerContext -> {
            String cron = "getCron()";
            //获取定时任务周期表达式
            CronTrigger trigger = new CronTrigger(cron);
            return trigger.nextExecutionTime(triggerContext);
        });

        // 3、多个定时任务
        // 3.1 从数据库中查询所有需要执行的任务
        List<SysJobPO> list = sysJobService.getSysJobAll(SysJobPO.STATE_NORMAL);
        // 3.2 记录所有任务
        ArrayList<TriggerTask> tasks = new ArrayList<>();
        // 3.3 循环添加任务
//        list.forEach(e -> {
//            TriggerTask triggerTask = new TriggerTask(() -> {
//                System.out.println("执行定时任务：" + LocalDateTime.now().toLocalTime());
//            }, triggerContext -> {
//                System.out.println("执行Cron:" + t.get("corn").toString() + ",id=" + t.get("id").toString());
//                //如果需要动态的指定当前定时任务的执行corn。这里可以增加一步，查询数据库操作。如果任务corn不需要精确修改，corn可进行缓存。到期在去查询数据库。这里根据读者的需求自行取舍。
//                return new CronTrigger(t.get("corn").toString()).nextExecutionTime(triggerContext);
//            });
//            list.add(triggerTask);
//
//        });


    }


    /**
     * 执行单个定时任务，具体实现类中需要实现这个抽象方法
     */
    public abstract void taskService();

    /**
     * 执行单个定时任务，具体实现类中需要实现这个抽象方法
     */
    public abstract String getCron();

    @Autowired
    public void setSysJobService(SysJobService sysJobService) {
        this.sysJobService = sysJobService;
    }
}
